home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / bit / src / forms / FORMS / dial.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  197 lines

  1. /*
  2.  * dial.c
  3.  *
  4.  * Forms Object class: DIAL
  5.  *
  6.  * Written by: Mark Overmars
  7.  *
  8.  * Version 2.1 a
  9.  * Date: Sep 29,  1992
  10.  */
  11.  
  12. #include <malloc.h>
  13. #include <math.h>
  14. #include "gl/gl.h"
  15. #include <sys/types.h>
  16. #include "forms.h"
  17.  
  18. /* The special information for dial. */
  19. typedef struct {
  20.    float min;        /* minimal value of dial */
  21.    float max;        /* maximal value of dial */
  22.    float val;        /* current value of dial */
  23.    float step;          /* step size */
  24.    int always;          /* whether always returning value */
  25. } SPEC;
  26.  
  27. static void draw_dial(FL_OBJECT *ob)
  28. /* Draws a dial */
  29. {
  30.   float min,max,val;
  31.   int angle;
  32.   min = ((SPEC *)(ob->spec))->min;
  33.   max = ((SPEC *)(ob->spec))->max;
  34.   val = ((SPEC *)(ob->spec))->val;
  35.   angle = (int) (2700.0*(val-min)/(max-min));
  36.   fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,FL_DIAL_TOPCOL,FL_DIAL_BW);
  37.   pushmatrix();
  38.   translate(ob->x + ob->w/2.0 -0.5, ob->y+ob->h/2.0 -0.5,0.0);
  39.   if (ob->boxtype == FL_NO_BOX)
  40.     scale(ob->w,ob->h,1.0);
  41.   else
  42.     scale(0.9*ob->w,0.9*ob->h,1.0);
  43.   fl_color(ob->col1);
  44.   circf(0.0,0.0,0.5);
  45.   fl_color(BLACK);
  46.   circ(0.0,0.0,0.5);
  47.   rotate(-angle,'Z');
  48.   if (ob->type == FL_NORMAL_DIAL)
  49.   {
  50.     fl_color(ob->col2);
  51.     circf(-0.20,-0.20,0.07);
  52.     fl_color(BLACK);
  53.     circ(-0.20,-0.20,0.07);
  54.   }
  55.   else
  56.   {
  57.     fl_color(ob->col2);
  58.     pmv2(0.0,0.0);
  59.     pdr2(-0.04,0.0);
  60.     pdr2(-0.25,-0.25);
  61.     pdr2(0.0,-0.04);
  62.     pclos();
  63.     fl_color(BLACK);
  64.     move2(0.0,0.0);
  65.     draw2(-0.04,0.0);
  66.     draw2(-0.25,-0.25);
  67.     draw2(0.0,-0.04);
  68.     draw2(0.0,0.0);
  69.   }
  70.   popmatrix();
  71.   fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
  72.             ob->lcol,ob->lsize,ob->lstyle,ob->label);
  73. }
  74.  
  75. #define PI 3.14159
  76.  
  77. static int handle_mouse(FL_OBJECT *ob,float mousex,float mousey)
  78. /* Handle a mouse position change */
  79. {
  80.   SPEC *sp = (SPEC *) ob->spec;
  81.   double oldval,min,max,val;
  82.   double mx,my;
  83.   double angle;
  84.   min = sp->min;
  85.   max = sp->max;
  86.   val = sp->val;
  87.   oldval = val;
  88.   mx = mousex - (ob->x + ob->w/2.0);
  89.   my = mousey - (ob->y + ob->h/2.0);
  90.   if (mx == 0.0 && my == 0.0) return 0;
  91.   if (fabs(mx)>fabs(my))
  92.   {
  93.     angle = atan(my/mx);
  94.     if (mx>0) angle = 1.25*PI - angle;
  95.     else angle = 0.25*PI - angle;
  96.   }
  97.   else
  98.   {
  99.     angle = atan(mx/my);
  100.     if (my>0) angle = 0.75*PI + angle;
  101.     else angle = -0.25*PI + angle;
  102.   }
  103.   if (angle<-0.25*PI) angle += 2.0*PI;
  104.   val = min + (max-min)*angle/(1.5*PI);
  105.   if (sp->step != 0.0) val = (int) (val/sp->step +0.5) * sp->step;
  106.   if (val < min) val = min;
  107.   if (val > max) val = max;
  108.   if (fabs(val-oldval)<(max-min)/2.0)
  109.   {
  110.     sp->val = val;
  111.     if (val-oldval > 0.0001*(max-min) || val-oldval < -0.0001*(max-min))
  112.       { fl_redraw_object(ob); return 1; }
  113.   }
  114.   return 0;
  115. }
  116.  
  117. static int handle_dial(FL_OBJECT *ob,int event,float mx,float my,char key)
  118. /* Handles an event */
  119. {
  120.   SPEC *sp = (SPEC *) ob->spec;
  121.   switch (event)
  122.   {
  123.     case FL_DRAW:
  124.     draw_dial(ob);
  125.     return 0;
  126.     case FL_PUSH:
  127.     case FL_MOUSE:
  128.         return ( handle_mouse(ob,mx,my)  && sp->always);
  129.     case FL_RELEASE:
  130.         return (! sp->always);
  131.     case FL_FREEMEM:
  132.     free(ob->spec);
  133.     return 0;
  134.   }
  135.   return 0;
  136. }
  137.  
  138. /*------------------------------*/
  139.  
  140. FL_OBJECT *fl_create_dial(int type,float x,float y,float w,float h,char label[])
  141. /* creates an object */
  142. {
  143.   FL_OBJECT *ob;
  144.   ob = fl_make_object(FL_DIAL,type,x,y,w,h,label,handle_dial);
  145.   ob->col1 = FL_DIAL_COL1;
  146.   ob->col2 = FL_DIAL_COL2;
  147.   ob->align = FL_DIAL_ALIGN;
  148.   ob->lcol = FL_DIAL_LCOL;
  149.  
  150.   ob->spec = (int *) fl_malloc(sizeof(SPEC));
  151.   ((SPEC *)(ob->spec))->min = 0.0;
  152.   ((SPEC *)(ob->spec))->max = 1.0;
  153.   ((SPEC *)(ob->spec))->val = 0.5;
  154.   ((SPEC *)(ob->spec))->step = 0.0;
  155.   ((SPEC *)(ob->spec))->always = TRUE;
  156.  
  157.   return ob;
  158. }
  159.  
  160. FL_OBJECT *fl_add_dial(int type, float x, float y, float w, float h, char label[])
  161. /* Adds an object */
  162. {
  163.   FL_OBJECT *ob;
  164.   ob = fl_create_dial(type,x,y,w,h,label);
  165.   fl_add_object(fl_current_form,ob);
  166.   return ob;
  167. }
  168.  
  169. void fl_set_dial_value(FL_OBJECT *ob,float val)
  170. {
  171.   ((SPEC *)(ob->spec))->val = val;
  172.   fl_redraw_object(ob);
  173. }
  174. void fl_set_dial_bounds(FL_OBJECT *ob,float min,float max)
  175. {
  176.   ((SPEC *)(ob->spec))->min = min;
  177.   ((SPEC *)(ob->spec))->max = max;
  178.   fl_redraw_object(ob);
  179. }
  180.  
  181. float fl_get_dial_value(FL_OBJECT *ob)
  182.   { return ((SPEC *)(ob->spec))->val; }
  183.  
  184. void fl_get_dial_bounds(FL_OBJECT *ob,float *min,float *max)
  185. {
  186.   *min = ((SPEC *)(ob->spec))->min;
  187.   *max = ((SPEC *)(ob->spec))->max;
  188. }
  189.  
  190. void fl_set_dial_return(FL_OBJECT *ob, int value)
  191. /* Sets whether to return value all the time */
  192.   { ((SPEC *)(ob->spec))->always = value; }
  193.  
  194. void fl_set_dial_step(FL_OBJECT *ob, float value)
  195. /* Sets the step size to which values are rounded. */
  196.   { ((SPEC *)(ob->spec))->step = value; }
  197.